﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Net.Sockets;
using FreedomX2.Core.Log;
namespace FreedomX2.Core.Transport.SocketProvider
{
    class SocketClient
    {
        #region 内部定义变量
        Thread _RecesiveThread;
        private string _cIp = "192.168.1.100";
        private int _cPort = 61011;
        private System.Net.Sockets.TcpClient _etcpC;
        private StreamWriter swWriter; //用以向网络基础数据流传送数据　 
        private NetworkStream nsStream; //创建发送数据的网络基础数据流　 
        private bool _ConState = false;
        private string _linkid;
        #endregion

        public void ConnectTcpClient()
        {
            try
            {
                _etcpC = new System.Net.Sockets.TcpClient(_cIp, _cPort);

                nsStream = _etcpC.GetStream();//通过申请，并获取传送数据的网络基础数据流　　 

                swWriter = new StreamWriter(nsStream);//使用获取的网络基础数据流来初始化StreamWriter实例 

                _ConState = true;

                _linkid = _etcpC.Client.LocalEndPoint.ToString().Substring(_etcpC.Client.LocalEndPoint.ToString().IndexOf(':') + 1, _etcpC.Client.LocalEndPoint.ToString().Length - _etcpC.Client.LocalEndPoint.ToString().IndexOf(':') - 1);


                _RecesiveThread = new Thread(new ThreadStart(ReceiveChat));

                _RecesiveThread.Start();
            }
            catch (System.Exception ex)
            {
                ex.e();
            }
        }

        public SocketClient(string ip, int port)
        {
            try
            {

                _etcpC = new System.Net.Sockets.TcpClient(ip, port);

                nsStream = _etcpC.GetStream();//通过申请，并获取传送数据的网络基础数据流　　 

                swWriter = new StreamWriter(nsStream);//使用获取的网络基础数据流来初始化StreamWriter实例 

                _ConState = true;

                _RecesiveThread = new Thread(new ThreadStart(ReceiveChat));

                _RecesiveThread.Start();
            }
            catch (System.Exception ex)
            {
                ex.e();
            }
        }
        public static bool SendMessage(System.Net.Sockets.Socket socket, string message)
        {

            if (socket.Connected != false)
            {
                var st = SocketThread.CreateSocketThread(PType.Message);
                int lastSize = 0;
                var vMsgs = SocketBlocks.CreateBlocks(message, out lastSize);
                for (int i = 0; i < vMsgs.Count; i++)
                {
                    BlocksThreadSingle bts = new BlocksThreadSingle();
                    bts.BytesList.AddRange(vMsgs[i]);
                    bts.ID = st.ID;
                    bts.SerialID = st.SerialID;
                    bts.Size = (i + 1) == vMsgs.Count ? lastSize : vMsgs[i].Length;
                    bts.Custom = i;
                    byte[] buffer = SocketConvert.convertToBuffer(bts);

                    socket.SendBufferSize = ProtocolVar.DefaultPackageSize;
                    socket.Send(buffer);
                    Thread.Sleep(1);
                }
                return true;
            }
            else
            {
                return false;
            }

        }
        public static bool SendBytes(System.Net.Sockets.Socket socket, byte[] message)
        {

            if (socket.Connected != false)
            {
                var st = SocketThread.CreateSocketThread(PType.FileBlocks);
                int lastSize = 0;
                var vMsgs = SocketBlocks.CreateBlocks(message, out lastSize);
                for (int i = 0; i < vMsgs.Count; i++)
                {
                    BlocksThreadSingle bts = new BlocksThreadSingle();
                    bts.BytesList.AddRange(vMsgs[i]);
                    bts.ID = st.ID;
                    bts.SerialID = st.SerialID;
                    bts.Size = (i + 1) == vMsgs.Count ? lastSize : vMsgs[i].Length;
                    bts.Custom = i;
                    byte[] buffer = SocketConvert.convertToBuffer(bts);

                    socket.SendBufferSize = ProtocolVar.DefaultPackageSize;
                    socket.Send(buffer);
                    Thread.Sleep(1);
                }
                return true;
            }
            else
            {
                return false;
            }

        }
        public bool SendBytes(byte[] bytes)
        {
            if (_etcpC.Connected != false)
            {
                var st = SocketThread.CreateSocketThread(PType.FileBlocks);
                int lastSize = 0;
                var vMsgs = SocketBlocks.CreateBlocks(bytes, out lastSize);
                for (int i = 0; i < vMsgs.Count; i++)
                {
                    BlocksThreadSingle bts = new BlocksThreadSingle();
                    bts.BytesList.AddRange(vMsgs[i]);
                    bts.ID = st.ID;
                    bts.SerialID = st.SerialID;
                    bts.Size = (i + 1) == vMsgs.Count ? lastSize : vMsgs[i].Length;
                    bts.Custom = i;
                    byte[] buffer = SocketConvert.convertToBuffer(bts);

                    _etcpC.SendBufferSize = ProtocolVar.DefaultPackageSize;
                    _etcpC.Client.Send(buffer);
                    _etcpC.GetStream().Flush();
                    Thread.Sleep(1);
                }
                return true;
            }
            else
            {
                return false;
            }

        }
        public bool SendMessage(string message)
        {
            if (_etcpC.Connected != false)
            {
                var st = SocketThread.CreateSocketThread(PType.Message);
                int lastSize = 0;
                var vMsgs = SocketBlocks.CreateBlocks(message, out lastSize);
                for (int i = 0; i < vMsgs.Count; i++)
                {
                    BlocksThreadSingle bts = new BlocksThreadSingle();
                    bts.BytesList.AddRange(vMsgs[i]);
                    bts.ID = st.ID;
                    bts.SerialID = st.SerialID;
                    bts.Size = (i + 1) == vMsgs.Count ? lastSize : vMsgs[i].Length;
                    bts.Custom = i;
                    byte[] buffer = SocketConvert.convertToBuffer(bts);

                    _etcpC.SendBufferSize = ProtocolVar.DefaultPackageSize;
                    _etcpC.Client.Send(buffer);
                    _etcpC.GetStream().Flush();
                    Thread.Sleep(1);
                }
                return true;
            }
            else
            {
                return false;
            }

        }
        private void ReceiveChat()
        {
            bool keepalive = true;
            while (keepalive)
            {
                try
                {
                    Byte[] buffer = new Byte[ProtocolVar.DefaultPackageSize];
                    nsStream.Read(buffer, 0, buffer.Length);

                    SocketThread.ReceiveBytes(_etcpC.Client, buffer);
                }
                catch (System.Exception ex)
                {
                    ex.e();
                }
            }
        }
        public void Close()
        {
            try
            {

                swWriter.Dispose();
                nsStream.Dispose();
                _etcpC.Close();
                _RecesiveThread.Abort();
            }
            catch { }
        }
        /// <summary>
        /// 地址
        /// </summary>
        public string IP
        {
            get
            {
                return _cIp;
            }
            set
            {
                _cIp = value;
            }
        }

        /// <summary>
        /// 端口
        /// </summary>
        public int Port
        {
            get
            {
                return _cPort;
            }
            set
            {
                _cPort = value;
            }
        }

        public System.Net.Sockets.TcpClient TCPClient
        {
            get
            {
                return _etcpC;
            }
            set
            {
                _etcpC = value;
            }
        }

        public bool ConState
        {
            get
            {
                return _ConState;
            }
            set
            {
                _ConState = value;

            }
        }

        public string LinkID
        {
            get
            {
                return _linkid;
            }
            set
            {
                _linkid = value;
            }
        }
    }
}
